/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import tal.drivechain.chain.AbortChainException;
import tal.drivechain.gui.GUIModule;
import tal.drivechain.matchers.VarMatcher;
import tal.drivechain.variable.types.DataType;
import tal.drivechain.variable.Variable;
import tal.drivechain.gui.Bar;
import tal.drivechain.parsing.Range;
import tal.drivechain.plugin.Channel;
import tal.drivechain.variable.VarTableAction;
/**
 * 
 * @author Main
 */
public class Meter extends GUIModule implements ActionListener {
    private VarMatcher trigger, releaseTrigger;
    private Bar meter;
    private boolean releaseOnChange;
    private Variable onRelease, curValue;
    private VarTableAction setCurValue;

    @Override
    public void setupProperties() throws IllegalArgumentException, AbortChainException {
        component = meter = new Bar();
        super.setupProperties();
        curValue = new Variable("value", DataType.FLOAT, null, true);
        setCurValue = new VarTableAction("value", VarTableAction.Action.SET_ANY);
    }

    @Override
    public void setEnabled(Boolean value) {
        super.setEnabled(value);
        if (meter!=null) {
            meter.setEditable(enabled);
            meter.setEnabled(enabled);
        }
    }

    @Override
    public void setFont(Font value) {
        super.setFont(value);
        if (meter!=null) meter.setFont(font);
    }

    @Override
    public void setColor(Color value) {
        super.setColor(value);
        if (meter!=null) meter.setColor(color);
    }

    @Override
    public void setNegative(Boolean value) {
        super.setNegative(value);
        if (meter!=null) meter.setNegative(negative);
    }

    public void setTrigger(VarMatcher value) {
        trigger = value;
    } public VarMatcher getTrigger() { return trigger; }

    public void setReleaseTrigger(VarMatcher value) {
        releaseTrigger = (VarMatcher)value;
    } public VarMatcher getReleaseTrigger() { return releaseTrigger; }

    public void setOnRelease(Variable value) {
        onRelease = value;
    } public Variable getOnRelease() { return onRelease; }

    public void setReleaseOnChange(Boolean value) {
        releaseOnChange = value;
        if (meter!=null) {
            if (releaseOnChange)
                meter.addActionListener(this);
            else meter.removeActionListener(this);
        }
    } public boolean getReleaseOnChange() { return releaseOnChange; }

    public void setWidth(Integer value) {
        Dimension size = new Dimension(value, meter.getHeight());
        meter.setSize(size);
        meter.setPreferredSize(size);
        meter.setMinimumSize(size);
        if (container!=null) relayout();
    } public int getWidth() { return meter.getWidth(); }

    public void setHeight(Integer value) {
        Dimension size = new Dimension(meter.getWidth(), value);
        meter.setSize(size);
        meter.setPreferredSize(size);
        meter.setMinimumSize(size);
        if (container!=null) relayout();
    } public Object getHeight() { return meter.getHeight(); }

    public void setRange(Range value) {
        meter.setRange(value.getOrderedRange());
    } public Range getRange() { return new Range(meter.getRange()); }

    public void setVertical(Boolean value) {
        meter.setVertical(value);
    } public boolean getVertical() { return meter.isVertical(); }

    public void setLabel(String value) {
        meter.setLabel(value);
    } public String getLabel() { return meter.getLabel(); }

    @Override
    protected void msgReceived(Variable in, long timestamp, Channel channel) {
        if (trigger.matches(in, channel, this)) {
            try {
                double value = (Double)DataType.FLOAT.cast(in.getValue(this));
                meter.setValue(value);
            } catch (IllegalArgumentException ie) {
                log(ie.getMessage(), MSG.WARNING);
            }
        } if (releaseTrigger.matches(in, channel, this)) {
            release();
        }
    }

    public void actionPerformed(ActionEvent e) {
        if (releaseOnChange)
            release();
    }

    private void release() {
        curValue.setValue(meter.getValue(), true);
        setCurValue.set(curValue, localVars, this);
        sendToOutputs(onRelease, -1);
    }
}

